package com.mingqijia.gassafety.job.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.gap.basic.exception.BizException;
import com.gap.cache.redis.RedisCache;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.mingqijia.gassafety.authority.api.resp.config.DictionaryItemRespDTO;
import com.mingqijia.gassafety.authority.dal.helper.ConfigureHolder;
import com.mingqijia.gassafety.db.entity.Dtu;
import com.mingqijia.gassafety.db.entity.RecordDetector;
import com.mingqijia.gassafety.db.entity.redis.LatestLog;
import com.mingqijia.gassafety.db.entity.vo.EquipmentListParamVO;
import com.mingqijia.gassafety.db.influxdb.config.InfluxDBConfiguration;
import com.mingqijia.gassafety.db.mapper.DictionaryMapper;
import com.mingqijia.gassafety.db.mapper.DtuMapper;
import com.mingqijia.gassafety.db.mapper.RecordControllerMapper;
import com.mingqijia.gassafety.db.mapper.RecordDetectorMapper;

import com.mingqijia.gassafety.db.mapper.*;
import com.mingqijia.gassafety.job.feign.ConsoleSkFeignClient;
import com.mingqijia.gassafety.job.request.ConsoleSkSupplierListRequest;

import com.mingqijia.gassafety.job.request.EquipmentListRequest;
import com.mingqijia.gassafety.job.request.LatestLogListRequest;
import com.mingqijia.gassafety.job.response.AlarmSupplierListVo;
import com.mingqijia.gassafety.job.response.ConsoleSkSupplierListResponse;
import com.mingqijia.gassafety.job.response.DtuListResponse;
import com.mingqijia.gassafety.job.response.EquipmentDetailResponse;
import com.mingqijia.gassafety.job.service.EquipmentService;
import com.mingqijia.gassafety.job.service.LatestLogService;
import com.mingqijia.gassafety.job.service.cmp.EquipmentCmpService;
import com.mingqijia.gassafety.shared.constant.Constants;
import com.mingqijia.gassafety.shared.constant.EquipmentStatus;
import com.mingqijia.gassafety.shared.constant.EquipmentType;
import com.mingqijia.gassafety.shared.utils.EntityUtils;
import com.mingqijia.gassafety.shared.utils.RedisCacheExt;
import com.mingqijia.gassafety.shared.utils.commonUtils.PageUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author zhangfei
 * @version 1.0.0
 * @ClassName EquipmentServiceImpl.java
 * @Description
 * @createTime 2022年03月11日
 */
@Slf4j
@Service
public class EquipmentServiceImpl extends ServiceImpl<DtuMapper, Dtu> implements EquipmentService {

    @Autowired
    DtuMapper dtuMapper;
    @Autowired
    InfluxDBConfiguration influxDBConnect;
    @Autowired
    RedisCache redisCache;
    @Autowired
    RedisCacheExt redisCacheExt;
    @Autowired
    DictionaryMapper dictionaryMapper;
    @Autowired
    LatestLogService latestLogService;
    @Autowired
    ConfigureHolder holder;

    @Autowired
    RecordControllerMapper recordControllerMapper;

    @Autowired
    RecordDetectorMapper recordDetectorMapper;

    @Autowired
    EquipmentCmpService equipmentCmpService;

    public static final String split_ = "-";
    public static final String split = ";";

    /**
     * 设备列表
     *
     * @param request
     * @return
     */
    public PageUtil<DtuListResponse> equipmentList(EquipmentListRequest request) {
        String spId = request.getSpId();
        Page<Dtu> page = PageHelper.startPage(request.getPage(), request.getPageSize());

        List<DtuListResponse> responses = new ArrayList<>();
        EquipmentListParamVO paramVO = new EquipmentListParamVO();
        BeanUtils.copyProperties(request, paramVO);
        paramVO.setSpId(spId);

        List<Map<String, Object>> maps = dtuMapper.selectListByCondition(paramVO);
        Map<String, String> dtuMap = new HashMap<>();
        log.info("equipmentList-maps:{}",JSONObject.toJSONString(maps));
        List<String> imeis = new ArrayList<>();
        maps.forEach(stringObjectMap -> {
            DtuListResponse dt = EntityUtils.mapToEntity(stringObjectMap, DtuListResponse.class);
            responses.add(dt);
            if (EquipmentType.GAS_ALARM_CONTROLLER.getCode().equals(dt.getEquipmentType())){
                imeis.add(stringObjectMap.get("iMEI")+"");
            }

        });
        log.info("equipmentList-responses:{}",JSONObject.toJSONString(responses));
        responses.forEach(d -> {
            dtuMap.put(d.getIMEI(), d.getDetectionType());
        });
        if (!CollectionUtil.isEmpty(responses)) {
            List<String> query = getQueryParams();
            List<Map<String, String>> customerCode = dictMap(null, query, null);
            Map<Long, List<RecordDetector>> collect =new HashMap<>();
            if (!CollectionUtils.isEmpty(imeis)){
                List<Long> ids = recordDetectorMapper
                        .selectByRecordIdAndDeviceIds(imeis, spId, EquipmentType.GAS_ALARM_CONTROLLER.getCode());
                if (!CollectionUtils.isEmpty(ids)) {
                    List<RecordDetector> detectors = recordDetectorMapper.selectByRecordId(ids);
                    log.info("equipmentList-detectors:{}", JSONObject.toJSONString(detectors));
                    collect = detectors.stream()
                            .collect(Collectors.groupingBy(RecordDetector::getRecordId, Collectors.toList()));
                }
            }
            //设备厂商名称
            ConsoleSkSupplierListResponse response = equipmentCmpService.supplierListRequest();
            log.info("调用厨房查询厂商接口返回：{}", response);
            List<AlarmSupplierListVo> supplierListVos = new ArrayList<>();
            if (response != null && response.getCode() == 0 && response.getData() != null && org.apache.commons.collections.CollectionUtils.isNotEmpty(response.getData())) {
                supplierListVos = response.getData();
            }
            for (DtuListResponse d : responses) {
                if (EquipmentType.GAS_ALARM_CONTROLLER.getCode().equals(d.getEquipmentType())) {
                    List<Map<String, Object>> objects = new ArrayList<>();
                    if (collect != null) {
                        collect.forEach((aLong, recordDetectors) -> {
                            if (recordDetectors.get(0).getDeviceId().contains(d.getIMEI())) {
                                recordDetectors.forEach(o -> {
                                    Map<String, Object> exts = new HashMap<>();
                                    Integer subId = ((RecordDetector)o).getSubId();
                                    exts.put("iMEI", ((RecordDetector)o).getDeviceId());
                                    exts.put("loop", 1);
                                    exts.put("point", subId);
                                    exts.put("detectionType", dtuMap.get(exts.get("iMEI"))
                                            == null ? "CO" : dtuMap.get(exts.get("iMEI")));
                                    objects.add(exts);
                                });
                            }
                        });
                        d.setExts(objects);
                        d.setLoopAmount(objects.size());
                    }
                }
                String equipmentManufacturer = d.getEquipmentManufacturer();
                String equipmentType = d.getEquipmentType();
                String communicationMode = d.getCommunicationMode();
                String detectionType = d.getDetectionType();
                String operators = d.getOperators();
                List<AlarmSupplierListVo> listVos = supplierListVos.stream().filter(a -> a.getAlarmSystemCode().equals(
                        equipmentManufacturer)).collect(Collectors.toList());
                if (!CollectionUtils.isEmpty(listVos)) {
                    d.setEquipmentManufacturer(listVos.get(0).getMsName());
                }
                d.setEquipmentType(getStringValue(customerCode,
                        equipmentType, query.get(1), "value", "alias"));
                d.setCommunicationMode(getStringValue(customerCode,
                        communicationMode, query.get(3), "value", "alias"));
                d.setOperators(getStringValue(customerCode,
                        operators, query.get(2), "value", "alias"));

                if (!StringUtils.isEmpty(detectionType) && detectionType.contains(split)) {
                    String stringValue = "";
                    String[] split = detectionType.split(EquipmentServiceImpl.split);
                    for (String s : split) {
                        stringValue = stringValue + getStringValue(customerCode,
                                s, query.get(4), "value", "alias") + "、";
                    }
                    if (stringValue.length() > 0) {
                        d.setDetectionType(stringValue.substring(
                                0, stringValue.length() - 1));
                    }
                } else {
                    d.setDetectionType(getStringValue(customerCode,
                            detectionType, query.get(4), "value", "alias"));
                }


            }
        }
        log.info("equipmentList-responses:{}",JSONObject.toJSONString(responses));
        PageUtil pageInfo = new PageUtil<>(request.getPage(), request.getPageSize(), page.getTotal(), responses);
        return pageInfo;
    }


    private List<String> getQueryParams() {
        List<String> query = new ArrayList<>();
        query.add("Equipment_manufacturer");
        query.add("Equipment_type");
        query.add("Operator");
        query.add("Communication_mode");
        query.add("Detection_type");
        return query;
    }


    private String getStringValue(List<Map<String, String>> customerCode, Object obj
            , String filter, String keys1, String keys2) {
        //分组过滤
        String value = null;
        try {
            List<Map<String, String>> maps = customerCode.stream().filter(stringStringMap -> {
                return stringStringMap.get("dict_code").equals(filter);
            }).collect(Collectors.toList());
            log.info("getStringValue-字典值{}", JSONObject.toJSONString(maps));
            value = "";
            for (Map<String, String> map : maps) {
                if (map.get(keys1).equals(obj)) {
                    value = map.get(keys2);
                }
            }
        } catch (Exception e) {
            log.error("getStringValue-error:{}", e);
        }
        return value;
    }


    public List<Map<String, String>> dictMap(String type, List<String> types, String spId) {
        List<Map<String, String>> maps = dictionaryMapper.selectKeyValue(type, types, spId);
        if (CollectionUtil.isEmpty(maps)) throw new BizException("未查询到客户相关字典数据,请联系管理员");
        return maps;
    }

    @Override
    public List<Dtu> queryEquipmentList(LatestLogListRequest request) {
        return dtuMapper.getDetectorList(request.getImei(), request.getEquipmentName(),
                request.getEquipmentTypes(), request.getSpId(), request.getImeiList(), request.getSubsCode(),
                request.getCustName(), request.getCustAddress(), request.getCustPhone(), request.getIndustryType(),
                request.getEquipmentModel(), request.getEquipmentManufacturer());
    }

    @Override
    public EquipmentDetailResponse detail(String imei) {
        EquipmentDetailResponse res = new EquipmentDetailResponse();
        LambdaQueryWrapper<Dtu> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(Dtu::getIMEI, imei).eq(Dtu::getIsDeleted, 0);
        Dtu dtu = dtuMapper.selectOne(lambdaQueryWrapper);
        if (dtu == null) {
            return null;
        }
        JSONObject json = (JSONObject) redisCacheExt.getHashObj(
                "department_" + dtu.getPath(), imei);
        LatestLog latestLog = latestLogService.get(imei,dtu.getSpId());
        if (latestLog != null) {
                int status = latestLog.getEquipmentStatus();
                if (status != EquipmentStatus.offline) {
                    res.setEquipmentStatus("在线");
                }
                if (status == EquipmentStatus.lowAlert || status == EquipmentStatus.highAlert) {
                    String[] model = dtu.getDetectionType().split(";");
                    for (String s : model) {
                        if (s.equals("CO")) {
                            res.setDetectionStatus1("异常");
                        }
                        if (s.equals("CH₄")) {
                            res.setDetectionStatus2("异常");
                        }
                    }
                }
                if (status == EquipmentStatus.broken) {
                    res.setAlarmStatus("故障");
                }
            //主电故障，备电故障，所以报警器电量异常
            if (latestLog.getEquipmentStatusInfo().equals("主电故障") || latestLog.getEquipmentStatusInfo().equals("备电故障")) {
                res.setAlarmElectricStatus("异常");
            }
        }
        res.setImei(imei);
        return res;
    }

    /**
     * 更新安装位置
     * @param position
     * @param deviceId
     */
    @Override
    public void updatePosition(String position, String deviceId, String date) {
        dtuMapper.updatePosition(position,deviceId,date);
    }

    /**
     * 根据imei获取
     *
     * @param imei
     * @return
     */
    public Map<String, Object> selectByImei(String imei, String spId) {
        String IMEI=imei;
        Map<String, Object> callMap = dtuMapper.selectCallInfoByImei(IMEI, spId);
        if (callMap == null||callMap.isEmpty()) return null;
        return callMap;
    }

    @Override
    public String getEquipmentManufacturerName(String equipmentManufacturerCode,String spId) {
        try {
            if (StringUtils.isEmpty(equipmentManufacturerCode)) {
                return "";
            }

            //设备厂商名称
            ConsoleSkSupplierListResponse response = equipmentCmpService.supplierListRequest();
            log.info("调用厨房查询厂商接口返回：{}", response);
            List<AlarmSupplierListVo> supplierListVos = new ArrayList<>();
            if (response != null && response.getCode() == 0 && response.getData() != null && org.apache.commons.collections.CollectionUtils.isNotEmpty(response.getData())) {
                supplierListVos = response.getData();
            }
            List<AlarmSupplierListVo> listVos = supplierListVos.stream().filter(a -> a.getAlarmSystemCode().equals(
                    equipmentManufacturerCode)).collect(Collectors.toList());
            if (CollectionUtils.isEmpty(listVos)) {
                return "";
            }
            return listVos.get(0).getMsName();
        }catch (Exception e){
            log.error("getEquipmentManufacturerName",e);
        }
        return "";
    }
}
